package com.lagou.config;

import com.lagou.pojo.Configuration;
import com.lagou.pojo.MappedStatement;
import com.lagou.pojo.ResultMap;
import com.lagou.pojo.ResultMapping;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.*;

public class XMLMapperBuilder {

    private Configuration configuration;

    public XMLMapperBuilder(Configuration configuration) {
        this.configuration = configuration;
    }

    public void parse(InputStream inputStream) throws Exception {

        Document document = new SAXReader().read(inputStream);
        Element rootElement = document.getRootElement();

        String namespace = rootElement.attributeValue("namespace");
        //获取所有resultmap标签
        List<Element> resultmaplist = rootElement.selectNodes("//resultMap");
        //封装resultmap
        resultmaplist.forEach((Element e) -> {
            elementForResultMap(e, namespace);
        });
        //解析 封装 mapstatement
        //修改xpath 获取slect,update.insert,delete 节点
        List<Element> list = rootElement.selectNodes("//select|//insert|//update|delete");
        for (Element element : list) {
            elementForStatement(element, namespace);
        }

    }

    //封装statement
    public void elementForStatement(Element element, String namespace) {
        String id = element.attributeValue("id");
        String resultType = element.attributeValue("resultType");
        String paramterType = element.attributeValue("paramterType");
        String sqlText = element.getTextTrim();
//            System.out.println(element.getName()+"当前节点的名称是");
        String sqlcommond = element.getName();//获取当前节点的节点名称 对应为 sql执行的类型
        MappedStatement mappedStatement = new MappedStatement();
        mappedStatement.setId(id);
        mappedStatement.setResultType(resultType);
        mappedStatement.setParamterType(paramterType);
        mappedStatement.setSql(sqlText);
        mappedStatement.setSqlCommondType(sqlcommond);
        mappedStatement.setNamespace(namespace);

        String key = namespace + "." + id;
        this.configuration.getMappedStatementMap().put(key, mappedStatement);
    }
    //解析ResultMap节点
    public void elementForResultMap(Element e, String namespace) {
        String id = e.attributeValue("id");
        String type = e.attributeValue("type");
        ResultMap resultMap = new ResultMap();
        resultMap.setId(id);
        resultMap.setType(type);
        Map<String, ResultMapping> resultMappingMap = new HashMap<>();

        //遍历当前节点解析result子节点
        Iterator iterator = e.elementIterator();
        while (iterator.hasNext()) {
            Element element = (Element) iterator.next();
            if (element.getName().equals("result")) {
                //获取父节点的 type 或oftype 或javatype
                //获取父节点
                Element parent = element.getParent();
                String ofType = parent.attributeValue("ofType");
                String javaType = parent.attributeValue("javaType");
                String type1 = parent.attributeValue("type");
//                System.out.println(ofType + "=oftype=" + javaType + "javatype=" + parent.getName() + element.getName());
                ResultMapping resultMapping = new ResultMapping();
                resultMapping.setProperty(element.attributeValue("property"));
                resultMapping.setColunm(element.attributeValue("column"));

                if (type1 != null) {
                    resultMapping.setType(type1);
                }
                if (ofType != null) {
                    resultMapping.setOfType(ofType);
                    //设置外层type值
                    resultMap.setOfType(ofType);
                }
                if (javaType != null) {
                    resultMapping.setJavaType(ofType);
                    resultMap.setJavaType(javaType);
                }
                resultMappingMap.put(element.attributeValue("column"), resultMapping);
            } else {
                Iterator iterator1 = element.elementIterator();
                while (iterator1.hasNext()) {
                    element = (Element) iterator1.next();
                    if (element.getName().equals("result")) {
                        //获取父节点的 type 或oftype 或javatype
                        //获取父节点
                        Element parent = element.getParent();
                        String ofType = parent.attributeValue("ofType");
                        String javaType = parent.attributeValue("javaType");
                        String type1 = parent.attributeValue("type");
//                        System.out.println(ofType + "=oftype=" + javaType + "javatype=" + parent.getName() + element.getName());
                        ResultMapping resultMapping = new ResultMapping();
                        resultMapping.setProperty(element.attributeValue("property"));
                        resultMapping.setColunm(element.attributeValue("column"));
                        //获取父亲节点的proprety值 在解析结果集时用于赋值
                        resultMapping.setParentProperty(parent.attributeValue("property"));

                        if (type1 != null) {
                            resultMapping.setType(type1);
                        }
                        if (ofType != null) {
                            resultMapping.setOfType(ofType);
                            //设置外层type值
                            resultMap.setOfType(ofType);
                        }
                        if (javaType != null) {
                            resultMapping.setJavaType(javaType);
                            resultMap.setJavaType(javaType);
                        }
                        resultMappingMap.put(element.attributeValue("column"), resultMapping);
                    }

                }


            }

            resultMap.setResultMappingMap(resultMappingMap);
//            System.out.println(id + type + "解析到reslutmap");
            configuration.getMappedResultMap().put(namespace + id, resultMap);
        }


    }
}